#include <iostream>
using namespace std;

// 1. 捕获值
void lamba_capture_var()
{
    int a = 2;
    int b = 3;
    int ret = 0;

    // 1.无参数
    auto add_fun = [=]() {
        return a + b;
        };
    ret = add_fun();
    cout << "add_fun ret=" << ret << endl;

    // 2.有参数
    auto add_fun2 = [=](int c) {
        return a + b + c;
        };
    ret = add_fun2(5);
    cout << "add_fun2 ret=" << ret << endl;
}

// 2. 捕获引用
void lamba_capture_ref()
{
    int a = 2;
    int b = 3;
    int ret = 0;

    // 1.无参数
    auto add_fun = [&]() {
        a++;
        b++;
        return a + b;
        };
    ret = add_fun();
    cout << "a=" << a << endl;          // 3
    cout << "b=" << b << endl;          // 4
    cout << "add_fun ret=" << ret << endl;    // 7
}

// 3. 混合捕获 值,引用
void lamba_capture_mix()
{
    int a = 2;
    int b = 3;
    int ret = 0;

    auto add_fun = [=, &b]() {
        // a++;     // Error: 编译错误,不能修改外部变量
        b++;
        return a + b;
        };
    ret = add_fun();
    cout << "a=" << a << endl;          // 2
    cout << "b=" << b << endl;          // 4
    cout << "add_fun ret=" << ret << endl;    // 6
}

// 4. 捕获this
void lamba_capture_this()
{
    class Demo
    {
    private:
        int a;
        int b;
    public:
        Demo(int a_, int b_)
            :a(a_), b(b_)
        {

        }
        int add_fun()
        {
            auto add_fun_lamba = [this](int c) {
                return this->a + this->b + c;
                };

            return add_fun_lamba(5);
        }
    };

    Demo demo(2, 3);
    int ret = demo.add_fun();
    cout << "ret=" << ret << endl;
}

int main(void)
{
    lamba_capture_var();    // 1. 捕获值
    lamba_capture_ref();    // 2. 捕获引用
    lamba_capture_mix();    // 3. 混合捕获 值,引用
    lamba_capture_this();   // 4. 捕获this

    return 0;
}